package digimon.scheduler;

import digimon.organism.BodyOrganism;
import digimon.organism.Organism;
import digimon.organism.instructions.Instruction;
import digimon.organism.instructions.InstructionSet;
import digimon.organism.instructions.InstructionSetC;
import digimon.organism.instructions.InstructionSetM;
import digimon.organism.instructions.InstructionSetV;

public class ProgramRunner {
	private BodyOrganism bodyOrganism;
	Scheduler scheduler;
	
	public static final int BACK 	= 1;
	public static final int FRONT 	= 2;
	public static final int T_LEFT 	= 3;
	public static final int T_RIGHT = 4;

	public ProgramRunner(BodyOrganism bodyOrganism){
		setBodyOrganism(bodyOrganism);
		scheduler = new Scheduler(getBodyOrganism());
	}
	
	/**
	 * This piece of code is completely dependent on the InstructionSet
	 * Must find a way to resolve this <br>
	 * @return returnMessage the message returned to the View app <br>
	 * 1 - Go Back
	 * 2 - Go Front
	 * 3 - Turn Left
	 * 4 - Turn Right
	 */
	public int run() {
		int returnMessage = 0;
		// Get the next organism to execute
		Organism org = scheduler.getOrganismToRun();
		// If organism will not reproduce
		if(!org.isTimeToReproduce()){
			Instruction inst = (Instruction) org.getInstructions().get(org.getInstructionPointer());
			// increment the Instruction Pointer
			org.setInstructionPointer(org.getInstructionPointer()+1);
			switch(inst.getType()){
			
				/*
				 * Default InstructionSets
				 */
				case InstructionSet.NOP:
					// NOP instruction
					// Do nothing
					break;
				case InstructionSet.SEND_MSG:
					break;
					
				/*
				 * Communicator InstructionSet
				 */
				case InstructionSetC.SEND_MSG:
					break;
					
				/*
				 * Motor InstructionSet
				 */
				case InstructionSetM.GO_BACK:
					returnMessage = BACK;
					break;
				case InstructionSetM.GO_FRONT:
					returnMessage = FRONT;
					break;
				case InstructionSetM.TURN_LEFT:
					returnMessage = T_LEFT;
					break;
				case InstructionSetM.TURN_RIGHT:
					returnMessage = T_RIGHT;
					break;
					
				/*
				 * Vision InstructionSet
				 */
				case InstructionSetV.LOOK:
					break;
					
				default:
					break;
				
			}
		// Time to have some sex.. :-)
		} else {
			switch(org.getORG_TIPE()){
				case 0:
					// Generic Organism
					break;
				case 1:
					// Vision Organism
					break;
				case 2:
					// Communication Organism
					break;
				case 3:
					// Motor Organism
					break;
				default:
					break;
			}
		}
		// Put on the queue again
		scheduler.addToQueue(org);
		
		return returnMessage;
	}

	/**
	 * @return the bodyOrganism
	 */
	public BodyOrganism getBodyOrganism() {
		return bodyOrganism;
	}

	/**
	 * @param bodyOrganism the bodyOrganism to set
	 */
	public void setBodyOrganism(BodyOrganism bodyOrganism) {
		this.bodyOrganism = bodyOrganism;
	}
	
	

}
